package me.zhengjie.utils;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class MapUtil {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 将任意对象（特别是嵌套的Map和List）转换为Map<String, Object>
     */
    public static Map<String, Object> objectToMap(Object obj) {
        if (obj == null) {
            return null;
        }
        
        try {
            // 如果已经是Map，直接转换
            if (obj instanceof Map) {
                @SuppressWarnings("unchecked")
                Map<String, Object> result = (Map<String, Object>) obj;
                return result;
            }
            
            // 使用Jackson进行转换，确保所有类型都可序列化
            return objectMapper.convertValue(obj, Map.class);
        } catch (Exception e) {
            throw new RuntimeException("对象转换为Map失败: " + e.getMessage() + ", 对象类型: " + 
                (obj != null ? obj.getClass().getName() : "null"), e);
        }
    }

    /**
     * 将 Map 的所有 key 从下划线转为驼峰命名（递归处理嵌套结构）
     */
    public static Map<String, Object> underlineToCamel(Map<String, Object> map) {
        Map<String, Object> result = new LinkedHashMap<>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String camelKey = toCamelCase(entry.getKey());
            Object value = entry.getValue();

            if (value instanceof Map) {
                value = underlineToCamel((Map<String, Object>) value);
            } else if (value instanceof List) {
                value = processList((List<?>) value, true);
            }

            result.put(camelKey, value);
        }
        return result;
    }

    /**
     * 将 Map 的所有 key 从驼峰转为下划线命名（递归处理嵌套结构）
     */
    public static Map<String, Object> camelToUnderline(Map<String, Object> map) {
        Map<String, Object> result = new LinkedHashMap<>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String underlineKey = toUnderlineCase(entry.getKey());
            Object value = entry.getValue();

            if (value instanceof Map) {
                value = camelToUnderline((Map<String, Object>) value);
            } else if (value instanceof List) {
                value = processList((List<?>) value, false);
            }

            result.put(underlineKey, value);
        }
        return result;
    }

    private static List<Object> processList(List<?> list, boolean toCamel) {
        List<Object> result = new ArrayList<>();
        for (Object item : list) {
            if (item instanceof Map) {
                result.add(toCamel ? underlineToCamel((Map<String, Object>) item) : camelToUnderline((Map<String, Object>) item));
            } else {
                result.add(item);
            }
        }
        return result;
    }

    // 下划线转驼峰（例如：user_name -> userName）
    public static String toCamelCase(String str) {
        StringBuilder result = new StringBuilder();
        boolean upper = false;
        for (char c : str.toCharArray()) {
            if (c == '_') {
                upper = true;
            } else {
                result.append(upper ? Character.toUpperCase(c) : c);
                upper = false;
            }
        }
        return result.toString();
    }

    // 驼峰转下划线（例如：userName -> user_name）
    public static String toUnderlineCase(String str) {
        StringBuilder result = new StringBuilder();
        for (char c : str.toCharArray()) {
            if (Character.isUpperCase(c)) {
                result.append('_').append(Character.toLowerCase(c));
            } else {
                result.append(c);
            }
        }
        return result.toString();
    }
}
